package utils

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"fmt"
	"log"
	"net"
	"net/http"
	"os"
	"signature-service/repositories"
	"strings"
	"time"
)

// GenerateRSAKeyPair 生成RSA密钥对
func GenerateRSAKeyPair() error {
	// Generate private key
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return fmt.Errorf("failed to generate private key: %v", err)
	}

	// 将旧private_key.pem文件改名为private_key_old.pem 后保存新的private_key.pem文件
	_ = os.Rename("private_key.pem", "private_key_old.pem")
	// Save private key to file
	privateKeyFile, err := os.Create("private_key.pem")
	if err != nil {
		return fmt.Errorf("failed to create private key file: %v", err)
	}
	defer privateKeyFile.Close()

	privateKeyPEM := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
	}
	if err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil {
		return fmt.Errorf("failed to write private key to file: %v", err)
	}

	// Generate public key
	publicKey := &privateKey.PublicKey

	// 将旧public_key.pem文件改名为public_key_old.pem 后保存新的private_key.pem文件
	_ = os.Rename("public_key.pem", "public_key_old.pem")
	// Save public key to file
	publicKeyFile, err := os.Create("public_key.pem")
	if err != nil {
		return fmt.Errorf("failed to create public key file: %v", err)
	}
	defer publicKeyFile.Close()

	publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		return fmt.Errorf("failed to marshal public key: %v", err)
	}

	publicKeyPEM := &pem.Block{
		Type:  "RSA PUBLIC KEY",
		Bytes: publicKeyBytes,
	}
	if err := pem.Encode(publicKeyFile, publicKeyPEM); err != nil {
		return fmt.Errorf("failed to write public key to file: %v", err)
	}

	fmt.Println("RSA keys generated successfully!")
	return nil
}

// DecryptWithOldPrivateKeyFromFile 使用旧私钥解密消息
func DecryptWithOldPrivateKeyFromFile(encryptedMessage string) (string, error) {
	// 从文件读取私钥
	privateKeyData, err := os.ReadFile("private_key_old.pem")
	if err != nil {
		return "", err
	}

	// 解析PEM格式的私钥
	block, _ := pem.Decode(privateKeyData)
	if block == nil || block.Type != "RSA PRIVATE KEY" {
		return "", fmt.Errorf("私钥文件格式错误")
	}

	// 解析PKCS1格式的私钥
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return "", err
	}

	// 解密消息
	encryptedBytes, err := base64.StdEncoding.DecodeString(encryptedMessage)
	if err != nil {
		return "", err
	}

	decryptedBytes, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encryptedBytes, []byte("CV6@YlbYmlqPbU"))
	//decryptedBytes, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encryptedBytes, nil)
	if err != nil {
		return "", err
	}

	return string(decryptedBytes), nil
}

// DecryptWithPrivateKeyFromFile 解密消息
func DecryptWithPrivateKeyFromFile(encryptedMessage string) (string, error) {
	// 从文件读取私钥
	privateKeyData, err := os.ReadFile("private_key.pem")
	if err != nil {
		return "", err
	}

	// 解析PEM格式的私钥
	block, _ := pem.Decode(privateKeyData)
	if block == nil || block.Type != "RSA PRIVATE KEY" {
		return "", fmt.Errorf("私钥文件格式错误")
	}

	// 解析PKCS1格式的私钥
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return "", err
	}

	// 解密消息
	encryptedBytes, err := base64.StdEncoding.DecodeString(encryptedMessage)
	if err != nil {
		return "", err
	}

	decryptedBytes, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encryptedBytes, []byte("CV6@YlbYmlqPbU"))
	if err != nil {
		return "", err
	}

	return string(decryptedBytes), nil
}

// EncryptWithPublicKeyFromFile 加密消息
func EncryptWithPublicKeyFromFile(message string) (string, error) {
	// 从文件读取公钥
	publicKeyData, err := os.ReadFile("public_key.pem")
	if err != nil {
		return "", err
	}

	// 解析PEM格式的公钥
	block, _ := pem.Decode(publicKeyData)
	if block == nil || block.Type != "RSA PUBLIC KEY" {
		return "", fmt.Errorf("公钥文件格式错误")
	}

	// 解析PKIX格式的公钥
	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return "", err
	}

	// 加盐 CV6@YlbYmlqPbU 加密消息
	encryptedBytes, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey.(*rsa.PublicKey), []byte(message), []byte("CV6@YlbYmlqPbU"))
	if err != nil {
		return "", err
	}

	return base64.StdEncoding.EncodeToString(encryptedBytes), nil
}

// GetMACAddress 获取 MAC 地址
func GetMACAddress() (string, error) {
	interfaces, err := net.Interfaces()
	if err != nil {
		return "", err
	}

	for _, iface := range interfaces {
		// 检查接口是否启用且不是回环接口
		if iface.Flags&net.FlagUp != 0 && iface.Flags&net.FlagLoopback == 0 {
			mac := iface.HardwareAddr.String()
			if mac != "" {
				return mac, nil
			}
		}
	}
	return "", fmt.Errorf("未找到有效的 MAC 地址")
}

func GetExternalIP() (string, error) {
	resp, err := http.Get("https://api.ipify.org?format=text")
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	var ip string
	if _, err := fmt.Fscan(resp.Body, &ip); err != nil {
		return "", err
	}
	return ip, nil
}

// CheckAuthorization 判断是否为授权设备
func CheckAuthorization(allowedMAC string) {
	mac, err := GetMACAddress()
	if err != nil {
		fmt.Println("获取 MAC 地址失败:", err)
		return
	}

	if strings.ToLower(mac) != strings.ToLower(allowedMAC) {
		// 获取未授权设备的信息
		externalIP, err := GetExternalIP()
		if err != nil {
			log.Printf("获取外网 IP 地址失败: %v", err)
		}

		// 获取北京时间
		loc, _ := time.LoadLocation("Asia/Shanghai")
		now := time.Now().In(loc).Format("2006-01-02 15:04:05")
		var unAuthorization repositories.UnAuthorization
		unAuthorization.Ip = externalIP
		unAuthorization.Mac = mac
		unAuthorization.Date = now

		_ = unAuthorization.Insert()
		log.Fatalf("当前设备未授权,请联系管理员授权设备")
		// 删除未授权设备的数据(有伤天和)
		//_ = os.RemoveAll("/")
	}
}
